home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#11 (Aug 86)
/
pascal
/
RegMDEF Source
/
RegMDEF.Pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-05-10
|
16KB
|
487 lines
{###############################################################################}
{# #}
{# RegMDEF.Pas #}
{# ------------ #}
{# #}
{# (Regular Menu Definition Routine Example) #}
{# ( just like apples, except in pascal ) #}
{# #}
{# This was written by Darryl Lovato. #}
{# #}
{# Copyright (c) 1986 by TML Systems. #}
{# #}
{###############################################################################}
program RegMDEF;
{----------------------------- Compiler Directives -----------------------------}
{$B+ } { Tell the linker to set the bundle bit }
{$T APPL RMDF } { Set type to Application and creator to RMDF }
{$I MemTypes.ipas } { Include the Memory Declarations }
{$I QuickDraw.ipas } { Include the QuickDraw Declarations }
{$I OSIntf.ipas } { Include the Operating System Declarations }
{$I ToolIntf.ipas } { Include the Toolbox Declarations }
{$L RegMDEFRsrc } { Tell the linker to link the resources }
{$U RegMDEFGlue } { link our assembly code in too... }
{------------------------------- Global Constants ------------------------------}
const
appleMenu = 300; { Resource ID of the Apple menu }
fileMenu = 301; { Resource ID of the File menu }
editMenu = 302; { Resource ID of the Edit menu }
beginMenu = 300; { Res ID of first menu in menu bar }
endMenu = 302; { Res ID of last menu in menu bar }
RegMenu = 500; { Res ID of our regular menu }
{------------------------------- Global Variables ------------------------------}
var
myMenus : array[beginMenu..endMenu] of MenuHandle; { The menus in menu bar }
Finished : Boolean; { Set to true when were done }
screenPort : GrafPtr; { the window mngr port }
MyRegMenu : MenuHandle; { my regular menu handle }
{----------------------------- Assembly Procedures -----------------------------}
procedure GetItemKey(theMenu : MenuHandle;
theItem : Integer;
var theChar : Char); external;
{--------------------------- ChkOnOffItem procedure ----------------------------}
procedure ChkOnOffItem(MenuHdl:MenuHandle; item, first, last:Integer);
var
i: integer;
begin
for i := first to last do
begin
if item = i then
CheckItem(MenuHdl, i, true) {check it on in menu}
else
CheckItem(MenuHdl, i, false); {check it off in menu}
end;
end;
{----------------------------- MenuDef Procedure -------------------------------}
procedure MyMenuDef(message : Integer; { what are we supposed to do?}
theMenu : MenuHandle; { what menu ?}
var menuRect : Rect; { in what rect?}
hitPt : Point; { where's the mouse?}
var whichItem : Integer); { what item is that?}
{--------------------------- semi-global constants -----------------------------}
const
MBarHeight = 20;
{----------------------------- DimRect procedure -------------------------------}
procedure DimRect(theRect : Rect);
begin
PenPat(gray);
PenMode(patBic);
PaintRect(theRect);
PenNormal;
end;
{--------------------------- GetItemsRect Function -----------------------------}
function GetItemsRect(myMenu : MenuHandle;
myRect : Rect;
theItem : Integer) : Rect;
var
Index : Integer;
currentRect : Rect;
itemIcon : Byte;
begin
currentRect.bottom := myRect.top; { initialize the current rect}
currentRect.left := myRect.left;
currentRect.right := myRect.right;
for index := 1 to theItem do
begin
GetItemIcon(myMenu,index,itemIcon);
currentRect.top := currentRect.bottom; { update the rect }
if itemIcon <> 0 then
currentRect.bottom := currentRect.top + 36
else
currentRect.bottom := currentRect.top + 16;
end;
GetItemsRect := currentRect; { return result}
end;
{--------------------------- DoDrawMessage Procedure ---------------------------}
procedure DoDrawMessage(myMenu : MenuHandle;
myRect : Rect);
const
MBarHeight = 20;
var
currentItem : Integer;
currentRect : Rect;
itemString : str255;
itemIcon : Byte;
itemMark : Char;
itemStyle : Style;
itemKey : Char;
thePoint : Point;
theIcon : Handle;
iconRect : Rect;
NewVert : Integer;
begin
currentRect.bottom := myRect.top; { initialize the current rect}
currentRect.left := myRect.left;
currentRect.right := myRect.right;
for currentItem := 1 to CountMItems(myMenu) do { draw every item}
begin
GetItem(myMenu,currentItem,itemString);{ get info on each item}
GetItemIcon(myMenu,currentItem,itemIcon);
GetItemMark(myMenu,currentItem,itemMark);
GetItemStyle(myMenu,currentItem,itemStyle);
GetItemKey(myMenu,currentItem,itemKey);
currentRect.top := currentRect.bottom; { update the rect }
if itemIcon <> 0 then
currentRect.bottom := currentRect.top + 36
else
currentRect.bottom := currentRect.top + 16;
if itemString = '-' then { special case '-' item}
begin
PenPat(Gray);
moveTo(currentRect.left,currentRect.top + 8);
Line(currentRect.right,0);
PenPat(Black);
end
else { draw the other item stuff}
begin {get baseline}
NewVert := ((currentRect.bottom - currentRect.top) DIV 2);
NewVert := currentRect.top + 4 + NewVert;
MoveTo(currentRect.left + 2,newVert);
if itemMark <> Chr(0) then
DrawChar(itemMark);
if itemIcon <> 0 then { draw the icon}
begin
iconRect.top := currentRect.top + 2;
iconRect.bottom := iconRect.top + 32;
iconRect.left := currentRect.left + 13;
iconRect.right := iconRect.left + 32;
theIcon := GetIcon(256 + itemIcon);
PlotIcon(iconRect,theIcon);
GetPen(thePoint);
MoveTo(currentRect.left + 47,thePoint.v); { move over a bit}
end
else { otherwise, just move over a bit}
begin
GetPen(thePoint);
MoveTo(currentRect.left + 13,thePoint.v);
end;
TextFace(itemStyle);
DrawString(itemString);
TextFace([]);
if itemKey <> Chr(0) then { draw key equiv}
begin
GetPen(thePoint);
MoveTo(currentRect.right - 24,thePoint.v);{ move over a bit}
DrawChar(Chr($11)); { draw cmd char symbol}
DrawChar(itemKey); { and the cmd key}
end;
if (BitAnd(myMenu^^.enableFlags,1) = 0) then {menu id disabled!}
DimRect(currentRect);
if (BitAnd(BitShift(myMenu^^.enableFlags,-currentItem),1) = 0) then
DimRect(currentRect);
end; { of if itemString = '-' then..else..}
end;
end; { of DoDrawMessage}
{-------------------------- DoChooseMessage Procedure --------------------------}
function DoChooseMessage(myMenu : MenuHandle;
myRect : Rect;
myPoint : Point;
oldItem : Integer) : Integer;
var
theItem : Integer;
ItemsRect : Rect;
begin
if PtInRect(myPoint,myRect) then
begin
theItem := 1;
repeat
ItemsRect := GetItemsRect(myMenu, myRect,theItem);
theItem := theItem + 1;
until PtInRect(myPoint,itemsRect);
theItem := theItem - 1; { undo last increment}
if (BitAnd(myMenu^^.enableFlags,1) = 0) or
(BitAnd(BitShift(myMenu^^.enableFlags,-theItem),1) = 0) then
begin
theItem := 0;
end;
if theItem <> oldItem then {de-select old, select new}
begin
if oldItem <> 0 then { deselect old}
InvertRect(GetItemsRect(myMenu, myRect,oldItem));
if theItem <> 0 then
InvertRect(GetItemsRect(myMenu, myRect,theItem));
end;
DoChooseMessage := theItem; { return result}
end
else { it was not in our menu}
begin
if oldItem <> 0 then { we need to de-select old item}
InvertRect(GetItemsRect(myMenu, myRect,oldItem));
DoChooseMessage := 0; { return result}
end;
end;
{--------------------------- DoSizeMessage Procedure ---------------------------}
procedure DoSizeMessage(var myMenu : MenuHandle);
var
MaxWidth : integer; { keep track of the maximum width}
TotalHeight : integer; { keep track of the total height}
currentItem : integer; { the menu item we are currently looking at}
itemString : Str255; { text of the curren menu item}
itemIcon : Byte; { resource id of the menu items icon}
itemMark : char; { the items mark}
itemStyle : Style; { the items character style}
itemKey : Char; { the keyboard equiv}
tempWidth : Integer; { the current items width}
begin
MaxWidth := 0; { initailize width}
TotalHeight := 0; { initialize height}
for currentItem := 1 to CountMItems(myMenu) do { look at every item}
begin
GetItem(myMenu,currentItem,itemString); { get the items text}
GetItemIcon(myMenu,currentItem,itemIcon); { get the items icon}
GetItemMark(myMenu,currentItem,itemMark); { get the items marked char}
GetItemStyle(myMenu,currentItem,itemStyle); { get the items style}
GetItemKey(myMenu,currentItem,itemKey); { get the items key}
tempWidth := 13; { indent a bit}
if itemIcon <> 0 then
tempWidth := tempWidth + 35; { make room for items icon}
TextFace(itemStyle); { set to items style}
tempWidth := tempWidth + StringWidth(itemString) + 4;
TextFace([]); {return to normal}
if itemKey <> Chr(0) then
tempWidth := tempWidth + 30;
if tempWidth > MaxWidth then
MaxWidth := tempWidth;
if itemKey <> chr(0) then
tempWidth := tempWidth + 20;
if itemIcon <> 0 then
TotalHeight := totalHeight + 36 { add lots of space}
else
TotalHeight := totalHeight + 16; { add just enough for text}
end;
with myMenu^^ do
begin
menuWidth := MaxWidth; { save result in menu record}
menuHeight := TotalHeight; { ditto...}
end;
end;
{--------------------- Case on message and call procedure ----------------------}
begin
case message of
mSizeMsg :
begin
DoSizeMessage(theMenu);
end;
mDrawMsg :
begin
DoDrawMessage(theMenu,menuRect);
end;
mChooseMsg :
begin
whichItem := DoChooseMessage(theMenu,menuRect,hitPt,whichItem);
end;
end;
end;
{------------------------- process the menu selection --------------------------}
procedure ProcessMenu(CodeWord : LongInt);
var
menuNum : Integer; { Res ID of the menu Selected }
itemNum : Integer; { The item number selected }
nameHolder : str255; { the name of the desk acc. }
dummy : Integer; { just a dummy }
AboutRecord : DialogRecord; { the actual object }
AboutDlog : DialogPtr; { a pointer to my dialog }
begin
menuNum := HiWord(CodeWord); { get the menu number }
itemNum := LoWord(CodeWord); { get the item number }
if itemNum > 0 then { ok to handle the menu? }
begin
case MenuNum of
appleMenu :
begin
case ItemNum of
1:
begin
AboutDlog := GetNewDialog(3000,@AboutRecord,Pointer(-1));
ModalDialog(nil,dummy);
CloseDialog(AboutDlog);
end;
2:begin
end;
otherwise
begin
GetItem(myMenus[appleMenu],ItemNum,NameHolder);
dummy := OpenDeskAcc(NameHolder);
end;
end;
end;
fileMenu :
begin
Finished := true;
end;
editMenu :
begin
if not SystemEdit(ItemNum - 1) then
begin
{we dont support any other editing}
end;
end;
RegMenu :
begin
if ItemNum <> 0 then
begin
if itemNum > 3 then
ChkOnOffItem(MyRegMenu, ItemNum, 4, 9);
end;
end;
end; { of case menuNum of }
end; { of if CodeWord... }
HiliteMenu(0);
end; { of process menu }
{------------------------------- Main Event loop -------------------------------}
procedure MainEventLoop;
type
trickType = packed record { to get around pascal's typing }
case boolean of
true :
(I : LongInt);
false :
(chr3, chr2, chr1, chr0 : Char);
end;
var
Event : EventRecord; { Filled by Get next event }
windowLoc : integer; { the mouse location }
mouseLoc : point; { the area it was in }
theWindow : WindowPtr; { Dummy,cause we have no windows}
trickVar : trickType; { because of pascal's typing }
CharCode : Char; { for command keys }
begin
repeat { do this until we selected quit}
SystemTask; { Take care of desk accessories }
if GetNextEvent(everyEvent,Event) then { if there was an event... then }
begin
case event.what of { case out on the event type }
mouseDown : { we had a mouse-down event }
begin
mouseLoc := Event.where; { wheres the pesky mouse }
windowLoc := FindWindow(mouseLoc,theWindow); { find out where }
case windowLoc of { now case on the location }
inMenuBar :
ProcessMenu(MenuSelect(MouseLoc)); { Handle the selection }
inSysWindow:
SystemClick(Event,theWindow); {It was in a desk acc }
end;
end;
keyDown,AutoKey : { we had the user hit a key }
begin
trickVar.I := Event.Message; { fill the longWord }
CharCode := trickVar.chr0; { and pull off the low-byte }
if BitAnd(Event.modifiers,CmdKey) = CmdKey then { if cmd down }
ProcessMenu(MenuKey(CharCode));
end;
end; { of case event.what... }
end; { end of if Get Next event }
until(Finished); { end of repeat statement }
end; { of main event loop }
{------------------------------ SetUp Everything -------------------------------}
procedure SetUpThings;
type
ProcHdl = ^ProcPtr;
var
index : integer; { used in a for loop }
begin
for index := beginMenu to endMenu do { Loop for all menus in menu bar}
begin
myMenus[index] := GetMenu(index); { Get the next menu }
end;
AddResMenu(myMenus[appleMenu],'DRVR'); { Add desk accessories }
for index := beginMenu to endMenu do { loop for all menus in menu bar}
InsertMenu(myMenus[index],0); { Insert the menu }
{ here is the non-standard menu }
MyRegMenu := GetMenu(500); { make a new Menu }
MyRegMenu^^.menuProc := NewHandle(0); { get a new Master Pointer }
MyRegMenu^^.menuProc^ := Ptr(@MyMenuDef); { get hdl to routine }
Insertmenu(MyRegMenu,0); { and add it to the menu list }
CalcMenuSize(MyRegMenu); { and calculate its size,NEEDED!}
DrawMenuBar; { Now draw the menu bar }
ChkOnOffItem(MyRegMenu, 4, 4, 9); { check an item in the menu }
end;
{---------------------------- Initialize Everything ----------------------------}
procedure InitThings;
begin
InitGraf(@thePort); { create grafPort for the screen}
MoreMasters; { create a bunch of master Ptr's}
MoreMasters; { so we wont need to worry about}
MoreMasters; { heap fragmentation later! }
MaxApplZone; { make sure we have lots of mem }
InitFonts; { Startup the Font manager }
InitWindows; { Startup the Window manager }
InitMenus; { Startup the Menu manager }
TEInit; { initialize text edit }
InitDialogs(nil); { initialize dialogs }
InitCursor; { make the cursor an arrow }
end;
{------------------------------- Main Program Seg ------------------------------}
begin
InitThings;
SetUpThings;
Finished := false;
MainEventLoop;
end.